namespace study42 {
  /**
   * typeof 关键字
   * 1. 获取变量或表达式的类型
   * 2. 在运行时，typeof 用于获取变量的原始类型
   * 
   */

  // 1. 在运行时，typeof 用于获取变量的原始类型
  let str = "hello";
  console.log(typeof str); // "string"

  let num = 42;
  console.log(typeof num); // "number"

  let bool = true;
  console.log(typeof bool); // "boolean"

  let obj = { key: "value" };
  console.log(typeof obj); // "object"

  let func = () => { };
  console.log(typeof func); // "function"

  // 2. 在类型层面，typeof 用于获取一个变量或对象的类型
  let person = {
    name: "Alice",
    age: 30
  }

  type PersonType = typeof person

  let anotherPerson: PersonType = {
    name: "Bob",
    age: 25
  }

  // 3. 结合 typeof 和 keyof
  let person1 = {
    name: "Alice",
    age: 30
  }

  type Person1Keys = keyof typeof person1 // "name" | "age"

  function getValue(key: Person1Keys) {
    return person1[key]
  }

  console.log(getValue("name")) // "Alice"

  // 4. 应用场景
  // 动态类型定义 函数参数类型推导 类型保护
  // 传入某个对象，形参要指定该对象类型，用typeof
  function printPerson(p: typeof person1) {
    console.log(p.name, p.age);
  }
  // 等同于
  // (parameter) p: {
  //     name: string;
  //     age: number;
  // }
  printPerson({ name: "Alice", age: 30 });

  // 类型保护
  function process(value: string | number){
    if (typeof value === "string"){
      console.log(value.toUpperCase());  // 类型保护成功，value 被推导为 string
    }else{
      console.log(value.toFixed(2));  // value 被推导为 number
    }
  }
}
